#include "Tetrisstd.h"
#include "Game.h"

Game *g_game;

LRESULT WINAPI WinProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch( msg )
	{
		case WM_QUIT:
		case WM_CLOSE:
		case WM_DESTROY:
			g_game->SetRunning(false);
			break;
	}
	return DefWindowProc( hWnd, msg, wParam, lParam );
}


INT WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	g_game = new Game();
	if(!g_game->Preload())
		return false;

	RECT windowRect;
	windowRect.left = (long)0;
	windowRect.right = (long)SCREENWIDTH;
	windowRect.top = (long)0;
	windowRect.bottom = (long)SCREENHEIGHT;

	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX);

	wc.style		 = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc   = (WNDPROC)WinProc;
	wc.cbClsExtra	 = 0;
	wc.cbWndExtra	 = 0;
	wc.hInstance	 = hInstance;
	wc.hIcon		 = NULL;
	wc.hCursor	   = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = NULL;
	wc.lpszMenuName  = NULL;
	wc.lpszClassName = TITLE.c_str();
	wc.hIconSm	   = NULL;

	RegisterClassEx(&wc);

	DWORD dwStyle, dwExStyle;
	if (FULLSCREEN)
	{
		DEVMODE dm;
		memset(&dm, 0, sizeof(dm));
		dm.dmSize = sizeof(dm);
		dm.dmPelsWidth = SCREENWIDTH;
		dm.dmPelsHeight = SCREENHEIGHT;
		dm.dmBitsPerPel = 32;
		dm.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;

		if (ChangeDisplaySettings(&dm, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) 
		{
			MessageBox(NULL, "Display mode failed", NULL, MB_OK);
			FULLSCREEN = false;
		}

		dwStyle = WS_POPUP;
		dwExStyle = WS_EX_APPWINDOW;
		ShowCursor(FALSE);
	}
	else
	{
		dwStyle = WS_OVERLAPPEDWINDOW;
		dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
	}

	AdjustWindowRectEx(&windowRect, dwStyle, FALSE, dwExStyle);

	HWND hWnd = CreateWindowEx( 0,
		TITLE.c_str(),								 //window class
		TITLE.c_str(),								 //title bar
		dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,	  
		0, 0,											 //x,y coordinate
		windowRect.right - windowRect.left,			   //width of the window
		windowRect.bottom - windowRect.top,			   //height of the window
		0,											 //parent window
		0,											 //menu
		hInstance,									  //application instance
		0);	

	if (!hWnd)
	{
		return false;
	}

	//???

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	if(!g_game->Init(hWnd))
		return false;

	__int64 cntsPerSec = 0;
	QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
	double secsPerCnt = 1.0f / (double)cntsPerSec;

	__int64 lastTimeStamp = 0;
	QueryPerformanceCounter((LARGE_INTEGER*)&lastTimeStamp);

	g_game->SetRunning(true);

	MSG msg;
	while (g_game->IsRunning())
	{
		while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		__int64 currTimeStamp = 0;
		QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);

		double dt = double(currTimeStamp - lastTimeStamp) * secsPerCnt;
		lastTimeStamp = currTimeStamp;
		g_game->Update(dt);
		g_game->Render();
	}

	g_game->Close();

	if(g_game)
	{
		delete g_game;
		g_game = NULL; 
	}

	return 1;
}